package com.rachel.studyapp.video;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.SurfaceTexture;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.TextureView;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Util;
import com.rachel.studyapp.R;

/**
 * Created by zhengshaorui on 2017/8/26.
 */

public class CusVideoView extends RelativeLayout implements  ExoPlayer.EventListener, TextureView.SurfaceTextureListener, View.OnClickListener, SeekBar.OnSeekBarChangeListener, View.OnTouchListener {
    /**
     * const
     */
    private static final String TAG = "CusVideoView";
    private static final long ANIMATION_TIME = 5000;
    public static final float VIDEO_HEIGHT_PERCENT = 9 / 16.0f;
    public static final float VIDEO_ALPHA = 0.9f;
    public static final int AUTO_DISPEAR_TIME = 2000;
    public static final int AUTO_DISPEAR = 1;
    private static final int UPDATE_CURRENT_STATUS = 2;
    private static final int UPDATE_CURRENT_LOOP_TIME = 100; //每隔100ms刷新一下进度

    // play 状态
    private static final int READY = 0;
    private static final int PLAYING = 1;
    private static final int PAUSE = 2;
    private static final int FINISHED = 3;


    /**
     * ui
     */
    private ImageView mVideoCenterImage;
    private ImageView mFullImage;
    private ImageView mPreviewImg;
    private ImageView mTopBackImg;
    private TextureView mTextureView;
    private TextView mWholeTiemText;
    private TextView mCurrentTimeText;
    private SeekBar mSeekBar;
    private ProgressBar mLoadingProgress;
    private View mGroupView = null;
    private RelativeLayout mPreviewLy;
    private LinearLayout mToply,mInfoly;
    private TextView mPreviewCountText ;

    /**
     * logic
     */
    private int playingStatus ;
    private long mCurrentTime;
    private boolean isExpand = false;

    /**
     * varaiable
     */
    private Context mContext;
    private String mSourceUri;
    private SimpleExoPlayer mPlayer;
    private CusVideoListener mCusVideoListener;
    private Activity mActivity;


    private Handler mHandler = new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case AUTO_DISPEAR:
                    showBottomAndImgView(mTextureView,VISIBLE,true);
                    break;
                case UPDATE_CURRENT_STATUS:
                    if (mCurrentTimeText != null && mPlayer != null){
                        String time = CusVideoUtils.stringForTime(mPlayer.getCurrentPosition());
                        mCurrentTimeText.setText(time);
                        mCurrentTime = mPlayer.getCurrentPosition();
                        desideWeatherPlay();

                        if (mSeekBar != null){
                            mSeekBar.setProgress((int) (mPlayer.getCurrentPosition() * 100 /
                                                            mPlayer.getDuration()));
                        }
                        mHandler.sendEmptyMessageDelayed(UPDATE_CURRENT_STATUS,UPDATE_CURRENT_LOOP_TIME);
                    }
                    break;
            }
        }


    };

    /**
     * 滑动过程中，是否播放
     */
    private void desideWeatherPlay() {
        int[] location = new int[2];
        mTextureView.getLocationOnScreen(location);
        int moveheight = location[1];
        int parentheight = getResources().getDisplayMetrics().heightPixels;
        int targetheigth = mTextureView.getHeight();
       // Log.d(TAG, "desideWeatherPlay: "+moveheight+" "+parentheight+" "+targetheigth);
        if (getResources().getConfiguration().orientation ==
                Configuration.ORIENTATION_PORTRAIT){
            if (moveheight <=0 || (moveheight+targetheigth > parentheight)){
                pause();
                showBottomAndImgView(mTextureView, GONE,false);

            }
        }else{
            //不自动播放了，不然根手动的有冲突的，而且好像其他软件也是滑出屏幕就暂停也不自动播放
           /* if (playingStatus != READY){
                if (playingStatus != PLAYING) {
                    play();
                    showBottomAndImgView(mTextureView, GONE);
                }
            }*/
        }
    }


    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        Log.d(TAG, "onVisibilityChanged: "+visibility+ " "+changedView);
    }

    public CusVideoView(Context context) {
        this(context,null);
    }

    public CusVideoView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CusVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        
        mContext = context;
        this.removeAllViews();

        if (mGroupView == null){
            mGroupView = LayoutInflater.from(context).inflate(R.layout.cusviedoplayer_layout,null);
            this.addView(mGroupView);
            mTextureView = (TextureView) mGroupView.findViewById(R.id.videosdk_textureview);
            mVideoCenterImage = (ImageView) mGroupView.findViewById(R.id.videosdk_videoimg);
            mWholeTiemText = (TextView) mGroupView.findViewById(R.id.videosdk_wholetime);
            mCurrentTimeText = (TextView) mGroupView.findViewById(R.id.videosdk_currenttime);
            mSeekBar = (SeekBar) mGroupView.findViewById(R.id.videosdk_seekbar);
            mLoadingProgress = (ProgressBar) mGroupView.findViewById(R.id.videosdk_loadingprogress);
            mPreviewLy = (RelativeLayout) mGroupView.findViewById(R.id.videosdk_preview_ly);
            mPreviewCountText = (TextView) mGroupView.findViewById(R.id.videosdk_info_count);
            mFullImage = (ImageView) mGroupView.findViewById(R.id.videosdk_to_full);
            mPreviewImg = (ImageView) mGroupView.findViewById(R.id.videosdk_preview_img);
            mToply = (LinearLayout) mGroupView.findViewById(R.id.videosdk_topbar);
            mInfoly = (LinearLayout) mGroupView.findViewById(R.id.videosdk_info_ly);
            mTopBackImg = (ImageView) mGroupView.findViewById(R.id.videosdk_top_img);

            
            mTopBackImg.setOnClickListener(this);
            mSeekBar.setProgress(0);
            mTextureView.setOnClickListener(this);
            mSeekBar.setOnSeekBarChangeListener(this);
            mSeekBar.setOnTouchListener(this);
            mFullImage.setOnTouchListener(this);
            mTopBackImg.setOnTouchListener(this);
            mVideoCenterImage.setOnClickListener(this);
            mTextureView.setSurfaceTextureListener(this);
            adjustSize(Configuration.ORIENTATION_PORTRAIT);
        }

    }

    /**
     * 设置sourceuri
     * @param uri
     */
    public CusVideoView setSourceUri(Activity activity,String uri, CusVideoListener listener) {
        mCusVideoListener = listener;
        mActivity = activity;
        mSourceUri = uri;
        if (uri != null && playingStatus == READY){
            checkPlayer(uri);
            showReadyPlayView();
        }
        return this;
    }

    /**
     * 设置要显示的次数
     * @param text
     */
    public CusVideoView setInfoCount(String text){
        if (mPreviewCountText != null) {
            mPreviewCountText.setText(text);
        }
        return this;
    }

    /**
     * 设置视频上要显示的内容
     * @param text
     */
    public CusVideoView setinfoText(String text){
        TextView toptext = (TextView) mToply.getChildAt(1);
        toptext.setText(text);
        TextView infotext = (TextView) mInfoly.getChildAt(0);
        infotext.setText(text);
        return this;
    }
    public CusVideoView setPrevieImge(int resid){
        mPreviewImg.setImageResource(resid);
        return this;
    }



    public void play(){
        if (mPlayer != null ){
            if (mSourceUri != null && playingStatus != PLAYING) {
                mPlayer.seekTo(mCurrentTime - 1);
                mPlayer.setPlayWhenReady(true);
                playingStatus = PLAYING;
            }
        }
    }
    public void pause(){
        if (mSourceUri != null && playingStatus == PLAYING) {
            mPlayer.setPlayWhenReady(false);
            playingStatus = PAUSE;
        }
    }


    /**
     * 设置成16：9的格式
     */
    private void adjustSize(int dection) {

        LayoutParams params = (LayoutParams) mTextureView.getLayoutParams();

        if (dection == Configuration.ORIENTATION_LANDSCAPE){
            params.width = getResources().getDisplayMetrics().heightPixels;
            params.height = getResources().getDisplayMetrics().widthPixels;
        }else{
            int width = getResources().getDisplayMetrics().widthPixels;
            int height = getResources().getDisplayMetrics().heightPixels;
            if (height > width) { //正常情况下
                params.width = width;
                params.height = (int) (width * VIDEO_HEIGHT_PERCENT);
            }else{ //刚从横屏切回来
                params.width = height;
                params.height =  (int) (height * VIDEO_HEIGHT_PERCENT);;
            }

        }

        params.addRule(CENTER_IN_PARENT);
        mTextureView.setLayoutParams(params);
        mPreviewLy.setLayoutParams(params);


    }

    /**
     * 初始化 exoplayer
     * @param uri 设置要付款的uri
     */
    private void checkPlayer(String uri) {
        // 1. Create a default TrackSelector 创建一个通道选择器
        if (mPlayer == null) {
            BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
            TrackSelection.Factory videoTrackSelectionFactory =
                    new AdaptiveTrackSelection.Factory(bandwidthMeter);
            TrackSelector trackSelector =
                    new DefaultTrackSelector(videoTrackSelectionFactory);


            // 2. Create the player
            mPlayer = ExoPlayerFactory.newSimpleInstance(mContext, trackSelector);


            // Produces DataSource instances through which media data is loaded.
            DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(mContext,
                    Util.getUserAgent(mContext, "测试"), (TransferListener<? super DataSource>) bandwidthMeter);

            // Produces Extractor instances for parsing the media data.
            ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
            // This is the MediaSource representing the media to be played.
            MediaSource videoSource = new ExtractorMediaSource(
                    Uri.parse(uri),
                    //Uri.parse("http://www.wooyun.site/1987.mp4"),
                    dataSourceFactory,
                    extractorsFactory,
                    null,
                    null);
            // Prepare the player with the source.
            mPlayer.prepare(videoSource);
            mPlayer.addListener(this);
            // 3.binder the player to the mGroupView
            mPlayer.setVideoTextureView(mTextureView);
        }

    }

    /**
     * 释放exoplayer
     */
    public void releaseMedia(){
        if (mPlayer != null){
            mPlayer.stop();
            mPlayer.release();
            mTextureView = null;

        }
    }



    @Override
    public void onTimelineChanged(Timeline timeline, Object manifest) {
        String wholetime = CusVideoUtils.stringForTime(mPlayer.getDuration());
        mWholeTiemText.setText(wholetime);
        mCurrentTimeText.setText(CusVideoUtils.stringForTime(mPlayer.getCurrentPosition()));
        mHandler.sendEmptyMessageDelayed(UPDATE_CURRENT_STATUS,UPDATE_CURRENT_LOOP_TIME);

    }

    @Override
    public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
        Log.d(TAG, "onTracksChanged: ");
    }

    @Override
    public void onLoadingChanged(boolean isLoading) {
        Log.d(TAG, "onLoadingChanged: ");

    }

    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
        Log.d(TAG, "onPlayerStateChanged: "+playbackState);
        if (playbackState == ExoPlayer.STATE_ENDED){ //播放完成
            playingStatus = FINISHED;
            showBottomAndImgView(mTextureView,GONE,false);

        }
        //缓存ok
        if (playbackState == ExoPlayer.STATE_READY){
            showLoadingProgress(false);
        }
        //缓存阶段
        if (playbackState == ExoPlayer.STATE_BUFFERING){
            showLoadingProgress(true);
        }
        //没有任何数据
        if (playbackState == ExoPlayer.STATE_IDLE){
            checkPlayer(mSourceUri);
        }
    }

    @Override
    public void onPlayerError(ExoPlaybackException error) {
        Log.d(TAG, "onPlayerError: "+error);
    }

    @Override
    public void onPositionDiscontinuity() {
        Log.d(TAG, "onPositionDiscontinuity: ");
    }

    @Override
    public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
        Log.d(TAG, "onPlaybackParametersChanged: ");
    }



    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        playingStatus = READY;
        Log.d(TAG, "onSurfaceTextureAvailable: ");
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        Log.d(TAG, "onSurfaceTextureSizeChanged: ");
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        Log.d(TAG, "onSurfaceTextureDestroyed: ");
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        Log.d(TAG, "onSurfaceTextureUpdated: ");
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.videosdk_videoimg:
                showImageClickView();
                break;
            case R.id.videosdk_textureview:
                int isBottomVisiable = mPreviewLy.getVisibility();
                showBottomAndImgView(mTextureView,isBottomVisiable,true);
                break;


        }


    }




    private void showImageClickView() {
        int visiable = mPreviewLy.getVisibility();
        Log.d("zheng", "showImageClickView: "+playingStatus);
        // 视频准备好，第一次点击
        if (playingStatus == READY){
            play();
        }else if (playingStatus == PLAYING){//在视频播放的情况下，点击屏幕
            pause();
        }else if (playingStatus == PAUSE){ //在视频暂停的情况下，点击屏幕
            play();
        }else if (playingStatus == FINISHED){
            mPlayer.seekTo(0);
            play();
        }
        Log.d("zheng", "showImageClickView: "+playingStatus);
        showBottomAndImgView(mVideoCenterImage,visiable,true);
    }

    /**
     * 显示底部状态栏和中间的图片
     * @param isBottomVisiable
     */
    private void showBottomAndImgView(View v,int isBottomVisiable,boolean hidePreviewImg) {
        mHandler.removeMessages(AUTO_DISPEAR);
        if (playingStatus == READY){
            mVideoCenterImage.setImageResource(R.mipmap.videosdk_start);
        }else if (playingStatus == PLAYING) {
            if (hidePreviewImg){
                mPreviewImg.setVisibility(GONE);
            }else{
                mPreviewImg.setVisibility(VISIBLE);
            }
            mVideoCenterImage.setImageResource(R.mipmap.videosdk_pause);
        } else if (playingStatus == FINISHED){
            mVideoCenterImage.setImageResource(R.mipmap.videosdk_reload);
        }else {
            mVideoCenterImage.setImageResource(R.mipmap.videosdk_start);
        }
        if (playingStatus == PLAYING) {
            mHandler.sendEmptyMessageDelayed(AUTO_DISPEAR, AUTO_DISPEAR_TIME);
        }
        if (v.getId() == R.id.videosdk_textureview){
            if (isBottomVisiable == GONE){
                mPreviewLy.setVisibility(VISIBLE);
                if (hidePreviewImg){
                    mPreviewImg.setVisibility(GONE);
                }else{
                    mPreviewImg.setVisibility(VISIBLE);
                }
                mVideoCenterImage.setVisibility(VISIBLE);
                mTextureView.setAlpha(VIDEO_ALPHA);
                if (playingStatus == FINISHED){
                    mVideoCenterImage.setImageResource(R.mipmap.videosdk_reload);
                }
            }else{
                mPreviewLy.setVisibility(GONE);
                mVideoCenterImage.setVisibility(GONE);
                mTextureView.setAlpha(1);
            }
        }

        if (playingStatus == PLAYING){
            Log.d("zheng", "showBottomAndImgView: "+playingStatus);
            mHandler.sendEmptyMessageDelayed(AUTO_DISPEAR,AUTO_DISPEAR_TIME);
        }


    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (mPlayer != null){
            long seekTime = progress * mPlayer.getDuration() / 100;
            mCurrentTimeText.setText(CusVideoUtils.stringForTime(seekTime));

        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        long seekTime = seekBar.getProgress() * mPlayer.getDuration() / 100;
        mCurrentTime = seekTime;
        mPlayer.seekTo(seekTime);
    }

    /**
     * 隐藏progress
     * @param ishide
     */
    private void showLoadingProgress(boolean ishide){
        if (mLoadingProgress != null){
            if (ishide){
                mLoadingProgress.setVisibility(View.VISIBLE);
            }else{
                mLoadingProgress.setVisibility(View.GONE);
            }
        }
    }

    /**
     * 显示视频准备好的图片图片
     */
    private void showReadyPlayView() {
        mHandler.removeCallbacksAndMessages(null);
        mPreviewLy.setVisibility(VISIBLE);
        mVideoCenterImage.setVisibility(VISIBLE);
        mVideoCenterImage.setImageResource(R.mipmap.videosdk_start);
        mPreviewLy.setVisibility(VISIBLE);
        mTextureView.setAlpha(VIDEO_ALPHA);
    }

    /**
     * @param v
     * @param event
     * @return
     */
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v.getId() == R.id.videosdk_seekbar){
            switch (event.getAction()){

                case MotionEvent.ACTION_MOVE:
                    mHandler.removeCallbacksAndMessages(null);
                    Log.d(TAG, "Touch removeCallbacksAndMessages");
                    break;
                case MotionEvent.ACTION_UP:
                    mHandler.sendEmptyMessageDelayed(AUTO_DISPEAR,AUTO_DISPEAR_TIME);
                    mHandler.sendEmptyMessageDelayed(UPDATE_CURRENT_STATUS,UPDATE_CURRENT_LOOP_TIME);
                    break;
            }

        }

        switch (v.getId()){

            case R.id.videosdk_to_full:
                if (event.getAction() == MotionEvent.ACTION_DOWN){
                    Log.d("moon", "onTouch: "+isExpand);
                    if (!isExpand){
                        isExpand = true;
                        if (mCusVideoListener != null){
                            mCusVideoListener.
                                    setLandscaleOrPortrait(Configuration.ORIENTATION_LANDSCAPE);
                            adjustSize(Configuration.ORIENTATION_LANDSCAPE);
                            mToply.setVisibility(VISIBLE);
                            mInfoly.setVisibility(GONE);

                        }
                    }
                    return true; //防止和textureview干扰，直接消费掉
                }
                break;
            case R.id.videosdk_top_img:
                if (event.getAction() == MotionEvent.ACTION_DOWN){
                    if (isExpand) {
                        Log.d("moon", "ogetActionnTouch: "+isExpand);
                        isExpand = false;
                        mCusVideoListener.
                                setLandscaleOrPortrait(Configuration.ORIENTATION_PORTRAIT);
                        adjustSize(Configuration.ORIENTATION_PORTRAIT);
                        mToply.setVisibility(GONE);
                        mInfoly.setVisibility(VISIBLE);

                    }
                    return true;
                }
                break;

        }

        return false;
    }

    private void registerBroadcastReceiver() {
        /*if (mScreenReceiver == null) {
            mScreenReceiver = new ScreenEventReceiver();
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_SCREEN_OFF);
            filter.addAction(Intent.ACTION_USER_PRESENT);
            getContext().registerReceiver(mScreenReceiver, filter);
        }*/
    }

    private void unRegisterBroadcastReceiver() {
       /* if (mScreenReceiver != null) {
            getContext().unregisterReceiver(mScreenReceiver);
        }*/
    }

    /**
     * 监听锁屏事件的广播接收器
     */
    private class ScreenEventReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //主动锁屏时 pause, 主动解锁屏幕时，resume
            switch (intent.getAction()) {
                case Intent.ACTION_USER_PRESENT:

                    break;
                case Intent.ACTION_SCREEN_OFF:

                    break;
            }
        }
    }
}
